//Digital_tube.h
#include <regx52.h>
#include "Delay.h"

//这里是默认共阳级，但他是共阴极要取反  //0,1,2---9, . ，A,C，E，F
unsigned char code number_Digital[15]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x7F,0x88,0xC6,0x86,0x8E};




/**
  * @brief  返回字符串中‘.’的索引值数组，注意：字符串中第一个字符不应该是'.'
  * @param  字符串
	* @retval 
  */
unsigned char * get_str_point_index(unsigned char *str){
	unsigned char index=0,i=0;
	unsigned char point_index[8]={0};	//放在堆区,合法的字符串中'.'的索引不可能为0
	while(*str != '\0'){
		if(*str == '.'){
			point_index[i] = index;
			i++;
		}
		index++;
		str++;
	}
	return point_index;
	
}


/**
  * @brief  检查某字符后是否有‘.’，如果有返回1，否则返回0
  * @param  无
	* @retval true:1 ,false:0
  */
unsigned char C_add_point(unsigned char *point_index,unsigned char C_index){
	/*检查是索引是否存在于点索引数组中*/
	unsigned char i=0;
	while(point_index[i] != 0){	//结束
		if(C_index == point_index[i]-1){ //字符‘.’位于字符后
			return 1;
		}
		i++;
	}
	return 0;
}




/**
  * @brief  38译码器控制位选
  * @param  无
  * @retval 无
  */
void Digital_tube_pos(unsigned char pos)
{
	P2_2 = 0x01 & pos;
	P2_3 = 0x01 & (pos>>1);
	P2_4 = 0x01 & (pos>>2);

}




/**
  * @brief  参数输入“1.2Af”的字符串即可，若超出最大位，后面的忽略，若不在number_Digital中的字符，则不显示
  * @param  要显示的字符 (".aF17")中点不能在最前面
  * @retval 无
  */
void Digital_tube_show_char(unsigned char *str){
	/**
	'a':97
	'A':65
	'1':49	'9':57
	*/
	unsigned char index=0,num=0,point_num=0;
	unsigned char *point_index;
	unsigned char valid_chars = 0;
    unsigned char *temp = str;
	point_index = get_str_point_index(str);

	// 计算有效字符数量（不含 '.'）
    while(*temp != '\0'){
        if(*temp != '.') valid_chars++;
        temp++;
    }

	// 如果超过 8 个字符，最多显示 8 个
    if(valid_chars > 8) valid_chars = 8;

	while(*str != '\0'){
		num = (unsigned int) (*str);
		if(index>8-1){
			break;
		}
		if(*str == '.'){	//跳过字符'.'
			index--;
			point_num++;
		}
		
		Digital_tube_pos(valid_chars - index - 1);

		P0 = 0x00;
		Delayus(40);

		if('1'<=num && num<='9'){
			if(C_add_point(point_index,index+point_num)){
				P0 = ~number_Digital[num-48] | 0x80;
			}else{
				P0 = ~number_Digital[num-48];
			}
		}
		else{
			switch(*str){
				case 'A':
				case 'a':
					if(C_add_point(point_index,index+point_num)){
						P0 = ~number_Digital[11] | 0x80;
					}else{
						P0 = ~number_Digital[11];
					}
					break;
				case 'C':
				case 'c':
					if(C_add_point(point_index,index+point_num)){
						P0 = ~number_Digital[12] | 0x80;
					}else{
						P0 = ~number_Digital[12];
					}
					break;
				case 'E':
				case 'e':
					if(C_add_point(point_index,index+point_num)){
						P0 = ~number_Digital[13] | 0x80;
					}else{
						P0 = ~number_Digital[13];
					}
					break;
				case 'F':
				case'f':
					if(C_add_point(point_index,index+point_num)){
						P0 = ~number_Digital[14] | 0x80;
					}else{
						P0 = ~number_Digital[14];
					}
					break;
				default:
					P0 = 0x00;
			}
		}
		index++;
		str++;
		Delayus(80);
	}
}



/**
 * @brief  显示八位的数字，参数 unsigned int
 * @param  要显示的数字
 * @retval 无
 */
void show_LED_bumber(unsigned long num) {
    // 分解数字的每一位
	unsigned char display_started = 0; // 标记是否开始显示非零数字
    unsigned char digits[8];
    unsigned char i = 0;

    // 清空所有断选
    P0  = 0x00;

    // 如果输入是 0，则直接显示 0
    if (num == 0) {
        digits[0] = 0;
    } else {
        // 分解数字到每一位
        for (i = 0; i < 8 && num > 0; i++) {
            digits[i] = num % 10;
            num /= 10;
        }
    }

    // 从高位到低位依次显示，并跳过高位的 0
	for (i = 7; i < 8; i--) {
		// 如果 display_started 为 0，且当前位是 0，则跳过显示
		if (!display_started && digits[i] == 0) {
			continue;
		}

		// 一旦遇到非零数字，标记为已开始显示
		display_started = 1;

		P0 = 0x00;

		Digital_tube_pos(i); // 设置位选
		P0 = ~number_Digital[digits[i]]; // 设置段码

		Delayms(1);
	}
}

